#include <avr/io.h>
#include <string.h>  

#include "../avrx/avrx.h"

#include "maintask.h"
#include "key.h"


#define KEY_NULL	0
#define KEY_DOWN	1
#define KEY_UP 		2
#define KEY_HOLD    3

#define KEY_UP_DOWN_COUNT   10
#define KEY_UP_COUNT 		10
#define KEY_HOLD_COUNT    	100

static TimerControlBlock 	aKeyInTimer;		// The Timer queue   

struct SKeyInData
{
    unsigned char key_code;
    unsigned char key_up;
    unsigned char key_dw;
} sKeyData[3] = {{KEY_NULL,KEY_NULL,KEY_DOWN}
							,{KEY_NULL,KEY_NULL,KEY_DOWN}
							,{KEY_NULL,KEY_NULL,KEY_DOWN}};


							
void intKeyIn( void )
{
	KEY_IN_0_PORT &= _BV(KEY_IN_0);
	KEY_IN_1_PORT &= _BV(KEY_IN_1);
	KEY_IN_2_PORT &= _BV(KEY_IN_2);
	
	KEY_IN_0_DIR &= _BV(KEY_IN_0);
	KEY_IN_1_DIR &= _BV(KEY_IN_1);
	KEY_IN_2_DIR &= _BV(KEY_IN_2);	
}

void doIncKeyIn(struct SKeyInData * pKeyIn)
{
	if( pKeyIn->key_up < KEY_HOLD_COUNT )	
	{
		pKeyIn->key_up += 1;
		if( pKeyIn->key_up == KEY_UP_COUNT )
		{
			pKeyIn->key_code = KEY_UP;
			pKeyIn->key_dw = 0;
		}
		else if( pKeyIn->key_up == KEY_HOLD_COUNT )	
		{
			pKeyIn->key_code  = KEY_HOLD;			
			pKeyIn->key_dw = 0;
		}
	}	
}

void doDecKeyIn(struct SKeyInData * pKeyIn)
{
	if( pKeyIn->key_dw < KEY_UP_DOWN_COUNT )	
	{
		pKeyIn->key_dw += 1;
		if( pKeyIn->key_dw == KEY_UP_DOWN_COUNT )
		{			
			if( pKeyIn->key_up >= KEY_UP_COUNT )
			{
				pKeyIn->key_code = KEY_DOWN;
				pKeyIn->key_up = 0;			
			}
			else
				pKeyIn->key_code = KEY_NULL;
		}
	}	
}

unsigned int iKeyInterval = 0;
unsigned char ucKeyCode = 0;
void doKeyDecode(void)
{
	if( bit_is_clear(KEY_IN_0_PIN,KEY_IN_0) )
		doIncKeyIn(&sKeyData[0]);
	else
		doDecKeyIn(&sKeyData[0]);	
		
	if( bit_is_clear(KEY_IN_1_PIN,KEY_IN_1) )
		doIncKeyIn(&sKeyData[1]);
	else
		doDecKeyIn(&sKeyData[1]);	

	if( bit_is_clear(KEY_IN_2_PIN,KEY_IN_2) )
		doIncKeyIn(&sKeyData[2]);
	else
		doDecKeyIn(&sKeyData[2]);	
		
	if( sKeyData[0].key_code == KEY_UP)
	{
		PutMainActCmd(100 + KEY_UP_0, NULL);
		iKeyInterval = KEY_HOLD_COUNT;			
		sKeyData[0].key_code = KEY_NULL;		
	}
	else if( sKeyData[0].key_code == KEY_DOWN)
	{
		PutMainActCmd(100 + KEY_DOWN_0, NULL);
		iKeyInterval = KEY_HOLD_COUNT;					
		sKeyData[0].key_code = KEY_NULL;		
	}
	else if( sKeyData[0].key_code == KEY_HOLD)
	{
		PutMainActCmd(100 + KEY_HOLD_0, NULL);
		iKeyInterval = KEY_HOLD_COUNT;							
		sKeyData[0].key_code = KEY_NULL;		
	}
		
	if( sKeyData[1].key_code == KEY_UP)
	{
		PutMainActCmd(100 + KEY_UP_1, NULL);
		iKeyInterval = KEY_HOLD_COUNT;							
		sKeyData[1].key_code = KEY_NULL;		
	}
	else if( sKeyData[1].key_code == KEY_DOWN)
	{
		PutMainActCmd(100 + KEY_DOWN_1, NULL);
		iKeyInterval = KEY_HOLD_COUNT;									
		sKeyData[1].key_code = KEY_NULL;		
	}
	else if( sKeyData[1].key_code == KEY_HOLD)
	{
		PutMainActCmd(100 + KEY_HOLD_1, NULL);
		iKeyInterval = KEY_HOLD_COUNT;									
		sKeyData[1].key_code = KEY_NULL;		
	}
	
	if( sKeyData[2].key_code == KEY_UP)
	{
		PutMainActCmd(100 + KEY_UP_2, NULL);
		iKeyInterval = KEY_HOLD_COUNT;											
		sKeyData[2].key_code = KEY_NULL;				
	}	
	else if( sKeyData[2].key_code == KEY_DOWN)
	{
		PutMainActCmd(100 + KEY_DOWN_2, NULL);
		iKeyInterval = KEY_HOLD_COUNT;													
		sKeyData[2].key_code = KEY_NULL;
	}
	else if( sKeyData[2].key_code == KEY_HOLD)
	{
		PutMainActCmd(100 + KEY_HOLD_2, NULL);
		iKeyInterval = KEY_HOLD_COUNT;													
		sKeyData[2].key_code = KEY_NULL;		
	}
	
	if(iKeyInterval > 0)
	{
		iKeyInterval--; 
		if(iKeyInterval == 0)
		{
			PutMainActCmd(100 + KEY_OFF, NULL);
		}
	}	
}


Mutex Timeout;
AVRX_GCC_TASKDEF(KeyInTask, 35, 3)
{
	aKeyInTimer.semaphore = SEM_PEND;	// Need to initialize stack variables...	

	intKeyIn();
	
	AvrXDelay(&aKeyInTimer, 1500); 
	
	while(1) 
	{
		AvrXDelay(&aKeyInTimer, 10);        //   Delay 10ms	
		AvrXSetSemaphore(&Timeout);
		doKeyDecode();
	}
}

